package com.tcoiss.common.datasource.aspect;


import com.tcoiss.common.datasource.DBContextHolder;
import com.tcoiss.common.datasource.annotation.DB;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

/**
 * 数据切面处理
 *
 * @author zw
 */
@Aspect
@Component
public class DBAspect
{
    private static final Logger log = LoggerFactory.getLogger(DBAspect.class);

    // 配置织入点
    @Pointcut("@annotation(com.tcoiss.common.datasource.annotation.DB)")
    public void dbPointCut()
    {
        log.info("进入切点。。。。。。。。。。。。。。。。");
    }

    @Before("dbPointCut()")
    public void doBefore(JoinPoint joinPoint) {
        log.info("开始切换数据源。。。。。。。。。。。。。");
        DB db = null;
        try {
            db = getAnnotationLog(joinPoint);

            if (db == null)
            {
                return;
            }
            //更据注解上的数据库名称,查询数据源，并切换到该数据源
            String dbName = db.value();
            DBContextHolder.setDataSource(dbName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @After("dbPointCut()")
    public void doAfter(JoinPoint joinPoint){
        log.info("结束后清空数据源。。。。。。。。。。。。。");
        DBContextHolder.clearDataSource();
    }

    /**
     * 是否存在注解，如果存在就获取
     */
    private DB getAnnotationLog(JoinPoint joinPoint) throws Exception
    {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if(method != null){
            if (method.isAnnotationPresent(DB.class))
            {
                return method.getAnnotation(DB.class);
            }else if(method.getDeclaringClass().isAnnotationPresent(DB.class)){
                return method.getDeclaringClass().getAnnotation(DB.class);
            }
        }

        return null;
    }


}
